﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using AGPR.Locadora.Data;
using AGPR.Locadora.Utils;

namespace AGPR.Locadora.Model
{
    /// <summary>
    /// Classe de Endereço
    /// </summary>
    public class Endereco : IEndereco
    {
        private static ActiveRecord db = ActiveRecord.Instancia;

        #region Atributos

        /// <summary>
        /// Nome da Tabela no Banco de Dados
        /// </summary>
        public const string TABELA = "endereco";

        /// <summary>
        /// Código do Endereço
        /// </summary>
        public int id { get; set; }

        /// <summary>
        /// CEP do Endereço
        /// </summary>
        [Required]
        [StringLength(8)]
        [Display(Name = "CEP")]
        public string cep { get; set; }

        /// <summary>
        /// CEP do Endereço Formatado
        /// </summary>
        [Display(Name = "CEP")]
        public string Cep
        {
            get
            {
                return Format.formatarCEP(this.cep);
            }
        }

        /// <summary>
        /// Endereço
        /// </summary>
        [Required]
        [StringLength(65, MinimumLength = 5)]
        [Display(Name = "Endereço")]
        public string endereco { get; set; }

        /// <summary>
        /// Número do Endereço
        /// </summary>
        [Required]
        [StringLength(15)]
        [Display(Name = "Número")]
        public string numero { get; set; }

        /// <summary>
        /// Complemento do Endereço
        /// </summary>
        [Required]
        [StringLength(45)]
        [Display(Name = "Complemento")]
        public string complemento { get; set; }

        /// <summary>
        /// Bairro do Endereço
        /// </summary>
        [Required]
        [StringLength(45)]
        [Display(Name = "Bairro")]
        public string bairro { get; set; }

        /// <summary>
        /// Cidade do Endereço
        /// </summary>
        [Required]
        [StringLength(45)]
        [Display(Name = "Cidade")]
        public string cidade { get; set; }

        /// <summary>
        /// Estado do Endereço
        /// </summary>
        [Required]
        [StringLength(2)]
        [Display(Name = "Estado")]
        public string estado { get; set; }

        #endregion

        #region Create

        /// <summary>
        /// Retorna uma instância de Endereço populada
        /// </summary>
        /// <param name="dados">Dados</param>
        /// <returns>Endereço</returns>
        public static Endereco Create(dynamic dados = null)
        {
            Endereco endereco = new Endereco();

            if (dados != null)
            {
                endereco.id = Convert.ToInt32(dados["id_endereco"]);
                endereco.cep = dados["cep"];
                endereco.endereco = dados["endereco"];
                endereco.numero = dados["numero"];
                endereco.complemento = dados["complemento"];
                endereco.bairro = dados["bairro"];
                endereco.cidade = dados["cidade"];
                endereco.estado = dados["estado"];
            }

            return endereco;
        }

        #endregion

        #region Get

        /// <summary>
        /// Retorna um Endereço pelo ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Endereco Get(object id)
        {
            db.where("id_endereco", id);
            return Endereco.Create(db.selectOne(TABELA));
        }

        #endregion

        #region GetByCep

        /// <summary>
        /// Retorna uma nova Instância de Endereco a partir de um CEP especifico
        /// </summary>
        /// <param name="cep">CEP a ser consultado</param>
        /// <returns></returns>
        public static Endereco GetByCep(string cep)
        {
            CEP _cep = CEP.Get(cep);

            return new Endereco
            {
                cep = _cep.cep,
                endereco = _cep.endereco,
                bairro = _cep.bairro,
                cidade = _cep.cidade,
                estado = _cep.sigla_estado
            };
        }

        #endregion

        #region getNextID

        /// <summary>
        /// Retorna o Proximo ID do Endereço
        /// </summary>
        /// <returns>ID</returns>
        private int getNextID()
        {
            return db.max("id_endereco", TABELA) + 1;
        }

        #endregion

        #region Cadastrar

        /// <summary>
        /// Cadastra o Endereço na Base de Dados
        /// </summary>
        /// <returns>Endereco</returns>
        public Endereco Cadastrar()
        {
            this.id = this.id > 0 ? this.id : this.getNextID();

            db.insert(TABELA, new Dictionary<string, dynamic>
            {
                {"id_endereco", this.id},
                {"endereco", this.endereco},
                {"numero", this.numero},
                {"complemento", this.complemento},
                {"bairro", this.bairro},
                {"cidade", this.cidade},
                {"estado", this.estado},
                {"cep", Format.limparNumero(this.cep)}
            });

            return this;
        }

        #endregion

        #region Alterar

        /// <summary>
        /// Altera o Endereço na base de dados
        /// </summary>
        /// <returns>Endereco</returns>
        public Endereco Alterar()
        {
            if (this.id > 0)
            {
                db.where("id_endereco", this.id);
                db.update(TABELA, new Dictionary<string, dynamic>
                {
                    {"endereco", this.endereco},
                    {"numero", this.numero},
                    {"complemento", this.complemento},
                    {"bairro", this.bairro},
                    {"cidade", this.cidade},
                    {"estado", this.estado},
                    {"cep", Format.limparNumero(this.cep)}
                });
            }

            return this;
        }

        #endregion
    }
}
